package com.bjb.vr.common.service;

import cn.hutool.core.convert.Convert;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.bjb.vr.common.ao.*;
import com.bjb.vr.common.dto.ResDevice;
import com.bjb.vr.common.dto.ResGroup;
import com.bjb.vr.common.mapper.ResDeviceMapper;
import com.bjb.vr.common.mapper.ResGroupMapper;
import com.bjb.vr.common.result.BaseErrorCode;
import com.bjb.vr.common.result.BaseResult;
import com.bjb.vr.common.result.CommonResult;
import com.bjb.vr.common.utils.DateTimeUtil;
import com.bjb.vr.common.vo.UmsAccountVo;
import com.power.common.util.UUIDUtil;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.Assert;

import java.time.LocalDateTime;
import java.util.*;

/**
 * @author admin
 * @description 针对表【res_group(房间表)】的数据库操作Service实现
 * @createDate 2022-03-22 10:49:59
 */
@Service
public class ResGroupService extends ServiceImpl<ResGroupMapper, ResGroup> {

    @Autowired
    private ResGroupMapper resGroupDao;
    @Autowired
    UmsAccountService umsAccountService;
    @Autowired
    ResDeviceMapper resDeviceDao;
    @Autowired
    ResGroupMapper resGroupMapper;
    @Autowired
    ResDeviceService resDeviceService;


    public BaseResult<ResGroup> checkAdminGroup(String acctNo) {

        BaseResult<ResGroup> result = new CommonResult<ResGroup>(false);

        ResGroup ResGroup = resGroupDao.getAdminResGroup(acctNo);
        if (ResGroup != null) {
            result.setData(ResGroup);
            result = CommonResult.Ok().setResult(ResGroup);
        } else {
            result = CommonResult.Fail("管理端没有加入组");

        }
        return result;
    }


    public BaseResult<ResGroup> updateResGroupByGroupCode(ResGroup resGroup) {
        UpdateWrapper<ResGroup> wrap = new UpdateWrapper<>();

        wrap.set(Objects.nonNull(resGroup.getContentId()), "content_id", resGroup.getContentId());
        wrap.set(Objects.nonNull(resGroup.getSectionNo()), "section_no", resGroup.getSectionNo());

        wrap.set(Objects.nonNull(resGroup.getClassState()), "class_state", resGroup.getClassState());
        wrap.set(Objects.nonNull(resGroup.getSoundState()), "sound_state", resGroup.getSoundState());
        wrap.set(Objects.nonNull(resGroup.getLockState()), "lock_state", resGroup.getLockState());
        wrap.set(Objects.nonNull(resGroup.getPlayState()), "play_state", resGroup.getPlayState());
        wrap.set(Objects.nonNull(resGroup.getCtrlModeState()), "ctrl_mode_state", resGroup.getCtrlModeState());
        wrap.set(Objects.nonNull(resGroup.getTimeline()), "timeline", resGroup.getTimeline());
        wrap.set("gmt_modified", DateTimeUtil.getLocalDateTime(new Date()));
        wrap.eq("group_code", resGroup.getGroupCode());
        this.update(wrap);

        return CommonResult.Ok();
    }


    /**
     * 根据groupcode修改管理端连接状态
     *
     * @param groupCode
     * @param onlineState
     * @return
     */
    public BaseResult<ResGroup> updateResGroupAdmConStateByGroupCode(String groupCode, int onlineState) {
        LocalDateTime curTime = LocalDateTime.now();
        UpdateWrapper<ResGroup> wrap = new UpdateWrapper<>();
        wrap.set("adm_con_state", onlineState);
        wrap.set("gmt_modified", curTime);
        wrap.eq("group_code", groupCode);
        if (onlineState == 0) {
            wrap.set("adm_off_time", curTime);
        }
        this.update(wrap);

        return CommonResult.Ok();
    }

    public BaseResult<ResGroup> checkclientGroup(String udid) {

        BaseResult<ResGroup> result = new CommonResult<ResGroup>(false);
        ResGroup resGroup = resGroupDao.getClientResGroup(udid);
        if (resGroup != null) {
            if (resGroup.getGroupCode() != null && resGroup.getGroupCode().trim() != "") {
                result.setData(resGroup);
                result = CommonResult.Ok().setResult(resGroup);
            } else {
                result = CommonResult.Fail("groupCode must not empty");
            }
        } else {
            result = CommonResult.Fail("dev not join group");

        }
        return result;
    }

    public BaseResult<ResGroup> checkGroupCode(String groupCode) {

        BaseResult<ResGroup> result = new CommonResult<ResGroup>(false);
        if (StringUtils.isEmpty(groupCode)) {
            result = CommonResult.Fail("设备组编码不能为空");
            return result;
        }
        LambdaQueryWrapper<ResGroup> queryWrapper = Wrappers.lambdaQuery(ResGroup.class);
        queryWrapper.eq(ResGroup::getGroupCode, groupCode);
        ResGroup resGroup = this.getOne(queryWrapper);
        if (resGroup != null) {
            if (resGroup.getGroupCode() != null && resGroup.getGroupCode().trim() != "") {
                result.setData(resGroup);
                result = CommonResult.Ok().setResult(resGroup);
            } else {
                result = CommonResult.Fail("请正确填写设备组groupCode");
            }
        } else {
            result = CommonResult.Fail("设备组不正确！");

        }
        return result;
    }


    public Object queryGroupNumbers(String authorization) {

        // 查询用户信息
        UmsAccountAo umsAccountAo = UmsAccountAo.builder().authorization(authorization).build();
        UmsAccountVo accountInfo = umsAccountService.getAccountInfo(umsAccountAo);
        if (Objects.isNull(accountInfo)) {
            return CommonResult.Fail(BaseErrorCode.UNKNOWN_ERROR);
        }
        List<Map> map = new ArrayList<>();
        List<ResGroup> resGroups = resGroupDao.queryGroupInfo();
        for (ResGroup group : resGroups) {
            HashMap<String, Object> map1 = new HashMap<>();
            Object groupNumbers = resGroupDao.queryGroupNumbers(group.getId());
            map1.put("groupId", group.getId());
            map1.put("groupName", group.getGroupName());
            map1.put("groupCode", group.getGroupCode());
            map1.put("groupNumbers", groupNumbers);
            map1.put("admConState", group.getAdmConState());
            map.add(map1);
        }
        return map;
    }

    public Object queryOneGroupNumbers(ResDeviceAo resDeviceAo, String authorization) {

        // 查询用户信息
        UmsAccountAo umsAccountAo = UmsAccountAo.builder().authorization(authorization).build();
        UmsAccountVo accountInfo = umsAccountService.getAccountInfo(umsAccountAo);
        if (Objects.isNull(accountInfo)) {
            return CommonResult.Fail(BaseErrorCode.UNKNOWN_ERROR);
        }
        Long groupId = resDeviceAo.getGroupId();

        //第二个接口，查询每个组下所有在线和离线设备的信息
        if (resDeviceAo.getOnlineState() != null) {
            HashMap map = new HashMap();
            List<ResDevice> deviceByGroIdAndOn = resGroupDao.queryGroupDeviceByGroIdAndOn(groupId, resDeviceAo.getOnlineState());
            Object deviceByGroIdAndOnNums = resGroupDao.queryGroupDeviceByGroIdAndOnNums(groupId, resDeviceAo.getOnlineState());
            map.put("deviceByGroIdAndOn", deviceByGroIdAndOn);
            map.put("deviceByGroIdAndOnNums", deviceByGroIdAndOnNums);
            return map;
        }
        //第三个接口，查询每个组下单机设备总数量
        if (resDeviceAo.getMode() != null) {
            return resGroupDao.queryDeviceModeByMode(groupId, resDeviceAo.getMode());
        }
        //第一个接口，查询每个组下所有设备信息
        return resGroupDao.queryOneGroupNumbers(groupId);
    }


    /**
     * 获取分组课程状态信息
     *
     * @param udid
     * @return
     */
    public BaseResult<ResGroup> getGroupClassStateByUdid(String udid) {

        BaseResult<ResGroup> result = new CommonResult<ResGroup>(false);
        ResGroup ResGroup = resGroupDao.getGroupClassStateByUdid(udid);
        if (ResGroup != null) {
            result.setData(ResGroup);
            result = CommonResult.Ok().setResult(ResGroup);
        } else {
            result = CommonResult.Fail("设备端没有加入组");

        }
        return result;

    }

    //设备管理页面统计接口
    public Object queryDeviceAndGroup() {
        List<Map> map = new ArrayList<>();
        List<ResGroup> resGroups = resGroupDao.queryGroupInfo();
        long allGroupNumbers = 0;
        long allDeviceOnNotByGroIdAndOnNums = 0;
        long allDeviceOnByGroIdAndOnNums = 0;
        for (ResGroup group : resGroups) {
            HashMap<String, Object> map1 = new HashMap<>();
            Object groupNumbers = resGroupDao.queryGroupNumbers(group.getId());
            Object deviceOnNotByGroIdAndOnNums = resGroupDao.queryGroupDeviceByGroIdAndOnNums(Long.valueOf(group.getId().toString()), 0);
            Object deviceOnByGroIdAndOnNums = resGroupDao.queryGroupDeviceByGroIdAndOnNums(Long.valueOf(group.getId().toString()), 1);
            map1.put("groupId", group.getId());
            map1.put("groupName", group.getGroupName());
            map1.put("groupCode", group.getGroupCode());
            map1.put("groupNumbers", groupNumbers);
            map1.put("admConState", group.getAdmConState());
            map1.put("deviceOnNotByGroIdAndOnNums", deviceOnNotByGroIdAndOnNums);
            map1.put("deviceOnByGroIdAndOnNums", deviceOnByGroIdAndOnNums);
            map.add(map1);
            allGroupNumbers = allGroupNumbers + Long.parseLong(groupNumbers.toString());
            allDeviceOnNotByGroIdAndOnNums = allDeviceOnNotByGroIdAndOnNums + Long.parseLong(deviceOnNotByGroIdAndOnNums.toString());
            allDeviceOnByGroIdAndOnNums = allDeviceOnByGroIdAndOnNums + Long.parseLong(deviceOnByGroIdAndOnNums.toString());
        }
        HashMap<String, Object> map2 = new HashMap<>();
        map2.put("allGroupNumbers", allGroupNumbers);
        map2.put("allDeviceOnNotByGroIdAndOnNums", allDeviceOnNotByGroIdAndOnNums);
        map2.put("allDeviceOnByGroIdAndOnNums", allDeviceOnByGroIdAndOnNums);
        map.add(map2);
        return map;
    }

    //设备管理全部和每组设备接口
    public Object queryDeviceInfoAndGroup(ResDeviceAo resDeviceAo, String authorization) {
        // 查询用户信息
        UmsAccountAo umsAccountAo = UmsAccountAo.builder().authorization(authorization).build();
        UmsAccountVo accountInfo = umsAccountService.getAccountInfo(umsAccountAo);
        if (Objects.isNull(accountInfo)) {
            return CommonResult.Fail(BaseErrorCode.UNKNOWN_ERROR);
        }
        //添加筛选条件、分组、分页
        List<ResDevice> deviceByGroIdAndOn = resDeviceDao.queryDeviceInfoAndGroup(resDeviceAo.getGroupId(), resDeviceAo.getOnlineState(), resDeviceAo.getMode(), resDeviceAo.getBattery(), resDeviceAo.getRemainMem(), resDeviceAo.getCurrent(), resDeviceAo.getSize());
        return deviceByGroIdAndOn;
    }

    //分组管理查询页面
    public Object queryGroupAllInfos(ResGroupAo resGroupAo) {
        String groupName = "";
        if (!"".equals(resGroupAo.getGroupName()) && resGroupAo.getGroupName() != null) {
            groupName = resGroupAo.getGroupName();
        }
        long current = (resGroupAo.getCurrent() - 1) * resGroupAo.getSize();
        List<ResGroupAo> groupList = resGroupDao.selectGroupList(groupName, current, resGroupAo.getSize());
        long total = resGroupDao.selectGroupListTotal(groupName);
        IPage<ResGroupAo> voIPage = new Page<ResGroupAo>(resGroupAo.getCurrent(), resGroupAo.getSize(), total);
        voIPage.setRecords(groupList);
        return voIPage;
    }

    //分组管理中 添加接口
    public Integer addGroupList(ResGroupAo resGroupAo) {
        // 判断组名是否存在
        long num = resGroupDao.selectGroupListTotal(resGroupAo.getGroupName());
        if (num > 0) {
            return -1;
        }
        ResGroup resGroup = new ResGroup();
        resGroup.setGroupName(resGroupAo.getGroupName());
        resGroup.setCapacity(resGroupAo.getCapacity() * 1024);
        resGroup.setGroupCode(UUIDUtil.getUuid32());
        resGroup.setContentId((long) -1);
        resGroup.setSectionNo(-1);
        resGroup.setClassState(-1);
        resGroup.setSoundState(-1);
        resGroup.setLockState(-1);
        resGroup.setPlayState(-1);
        resGroup.setCtrlModeState(-1);
        resGroup.setTimeline(-1);
        resGroup.setState(1);
        resGroup.setBundleUpdateSwitch(1);
        resGroup.setGmtCreate(LocalDateTime.now());
        return resGroupDao.insert(resGroup);

    }

    public boolean editGroupList(ResGroupAo resGroupAo) {
        ResGroup resGroup = new ResGroup();
        if (!"".equals(resGroupAo.getGroupName()) && resGroupAo.getGroupName() != null) {
            resGroup.setGroupName(resGroupAo.getGroupName());
        }
        if (resGroupAo.getBundleUpdateSwitch() != null) {
            resGroup.setBundleUpdateSwitch(resGroupAo.getBundleUpdateSwitch());
        }
        if (resGroupAo.getBundleId() != null) {
            resGroup.setBundleId(resGroupAo.getBundleId());
        }
        if (resGroupAo.getCapacity() != null) {
            resGroup.setCapacity(resGroupAo.getCapacity() * 1024);
        }
        resGroup.setId((long) resGroupAo.getId());
        resGroup.setGmtModified(LocalDateTime.now());
        int status = resGroupDao.updateGroup(resGroup);
        return status > 0;
    }

    public boolean removeGroupList(String ids) {
        String[] idArray = ids.split(",");
        Long[] intArray = Convert.toLongArray(idArray);
        return removeByIds(Arrays.asList(intArray));
    }

    public boolean editDeviceOfGroup(ResGroupAo resGroupAo) {
        String[] idArray = resGroupAo.getDeviceIds().split(",");
        for (String s : idArray) {
            int status = resGroupDao.editDeviceOfGroup(resGroupAo.getId(), Integer.parseInt(s));
        }
        return true;
    }

    public Object selectContentByDeviceId(ResDeviceContentAo resDeviceContentAo) {
        return resGroupDao.selectContentByDeviceId(resDeviceContentAo.getDevId());
    }

    public Integer deleteContentByDeviceId(ResDeviceContentAo resDeviceContentAo) {
        return resGroupDao.deleteContentByDeviceId(resDeviceContentAo.getUdid(), Convert.toStrArray(resDeviceContentAo.getIds()));
    }

    public Object selectDeviceAllByContentId(ResDeviceContentAo resDeviceContentAo) {
        HashMap<String, Object> map = new HashMap<>();
        //每组已经安装的总数
        Object groupDevicesIs = resGroupDao.queryAllNumbersByGroupContentId(resDeviceContentAo.getGroupId(), resDeviceContentAo.getId(), 1);
        //每组设备的详情
        List<ResDevice> groupDevicesAll = resGroupDao.groupDevicesAll(resDeviceContentAo.getGroupId(), resDeviceContentAo.getId());
        long groupNumbers = groupDevicesAll.size();
        Object groupDevicesIsNot = groupNumbers - Integer.parseInt(groupDevicesIs.toString());
        map.put("groupNumbers", groupNumbers);
        map.put("groupDevicesIs", groupDevicesIs);
        map.put("groupDevicesIsNot", groupDevicesIsNot);
        map.put("groupDevicesAll", groupDevicesAll);
        return map;
    }

    public boolean getGroupById(ResGroupAo resGroupAo) {
        //判断资源包所占的空间不能超过设备总空间
        ResGroupAo groupAo = resGroupDao.getGroupById(resGroupAo.getId());
        //获取资源包容量 contentSize
        long contentSize = groupAo.getContentSize();
        //获取组空间 capacity
        long capacity = groupAo.getCapacity() * 1024;
        return contentSize <= capacity;
    }


    public BaseResult<ResGroup> queryClassGroup(ResContentGroupAo resContentGroupAo) {
        Assert.notNull(resContentGroupAo.getContentId(), "资源id不能为空");
        Assert.notNull(resContentGroupAo.getGroupCode(), "设备分组code不能为空");

        BaseResult<ResGroup> result = new CommonResult<ResGroup>(false);
        LambdaQueryWrapper<ResGroup> lambdaQueryWrapper = new LambdaQueryWrapper();
        lambdaQueryWrapper.eq(ResGroup::getContentId, resContentGroupAo.getContentId());
        lambdaQueryWrapper.eq(ResGroup::getGroupCode, resContentGroupAo.getGroupCode());

        ResGroup resGroup = this.getOne(lambdaQueryWrapper);
        if (resGroup != null) {
            result.setData(resGroup);
            result = CommonResult.Ok().setResult(resGroup);
        } else {
            resGroup = new ResGroup();
            resGroup.setSoundState(-1);
            resGroup.setLockState(-1);
            resGroup.setPlayState(-1);
            resGroup.setCtrlModeState(-1);
            resGroup.setTimeline(-1);
            resGroup.setState(1);
            result = CommonResult.Ok().setResult(resGroup);
        }
        return result;
    }
}




